package com.efivestar.idm.api.service.lock.protocol.handler;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.efivestar.idm.api.common.Cons;
import com.efivestar.idm.api.domain.EventDomain;
import com.efivestar.idm.api.domain.WeixinJoinDeviceDomain;
import com.efivestar.idm.api.repository.EventMapper;
import com.efivestar.idm.api.repository.WeixinJoinDeviceMapper;
import com.efivestar.idm.api.service.WeixinService;
import com.efivestar.idm.api.util.ByteUtils;
import com.efivestar.idm.api.util.weixin.WeixinApi;
import com.efivestar.idm.api.util.weixin.bean.TemplateMessage;

import io.netty.buffer.ByteBuf;
import tk.mybatis.mapper.entity.Example;

/**
 * 请求远程开门.
 */
@Service
public class RequestOpenDoorLockProtocolHandler extends AbstractLockProtocolHandler{

    Logger logger = LoggerFactory.getLogger(this.getClass());


    @Autowired
    private EventMapper mapper;

    @Autowired
    private WeixinJoinDeviceMapper weixinJoinDeviceMapper;


    @Autowired
    private WeixinService weixinService;


    @Autowired
    private WeixinApi weixinApi;

    @Value("${service.domain:51ai.cc}")
    private String domain;


    @Value("${weixin.warningTemplateId:jZt8KiYA6wsIkVqNqL12GAfVnzZftFD895bEva0zPLA}")
    private String warningWeixinTemplateId;






    /**
     * @param buf
     * @param lockId
     * @return
     */
    @Override
    public byte[] handleData(ByteBuf buf, String lockId) {
        int length = buf.readableBytes();
        //跳过指令码，不读取
        buf.skipBytes(1);
        //跳过临时密码
        buf.skipBytes(4);
        //读取imei(设备编号)
        // String lockId = String.valueOf(buf.readCharSequence(length - getDataLenthWithoutDeviceId(), Charset.forName("utf-8")));
        //设置请求远程开门的状态.
        weixinService.requestLockRemoteControl(lockId);
        EventDomain event = EventDomain.builder().deviceId(lockId).eventType(Cons.REQUEST_OPEN_DOOR_EVENT_TPE).createTime(new Date()).build();
        mapper.insert(event);
        //发送通知给相关用户开锁
        sendNotification(lockId);
        return ByteUtils.hexToBytes("00");
    }


    /**
     * 发送通知信息.
     * 如果是劫持，则信息内容为红色， 并且可以查看摄像头.否则就是普通的信息，点击之后可以跳转到事件列表界面.
     * @param lockId
     */
    private void sendNotification(String lockId) {
        //发送微信通知.
        String now = DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss");
        List<WeixinJoinDeviceDomain> weixinJoinDeviceDomains = weixinJoinDeviceMapper.selectByExample(generateUserJoinDeviceExample(lockId));
        for (WeixinJoinDeviceDomain weixinJoinDeviceDomain : weixinJoinDeviceDomains) {

            String toUser = weixinJoinDeviceDomain.getOpenId();
            Map map = new HashMap<>();
            map.put("first", TemplateMessage.builder().value("请求远程开锁").color("#F00").build());
            map.put("keyword1", TemplateMessage.builder().value("您有远程开锁请求").color("#F00").build());
            map.put("keyword2", TemplateMessage.builder().value(now).build());
            String eventDetail = "http://" + domain + "/distIndex#/";
            boolean result = weixinApi.sendTemplateMessage(toUser, warningWeixinTemplateId, eventDetail,
                    map, null);
            logger.info("远程开锁请求推送，智能锁id:{}, toUser:{}, 结果： {}", new Object[]{lockId, toUser, result});
        }
    }


    private Example generateUserJoinDeviceExample(String deviceId) {
        Example example = new Example(WeixinJoinDeviceDomain.class);
        Example.Criteria criteria = example.createCriteria();
        if (StringUtils.isNotEmpty(deviceId)){
            criteria.andEqualTo("deviceId", deviceId);
        }
        return example;
    }



    @Override
    protected int getDataLenthWithoutDeviceId() {
        return 5;
    }


    public static byte[] subBytes(byte[] src, int begin, int count) {
        byte[] bs = new byte[count];
        System.arraycopy(src, begin, bs, 0, count);
        return bs;
    }

    @Override
    public String udpHead(){
        return Cons.UDP_HEAD_EF01;
    }

    @Override
    public String udpCommand(){
        return Cons.UDP_COMMAND_REQUEST_OPEN_DOOR;
    }


}






